package com.tree.security.config;

import com.tree.security.entity.Permission;
import com.tree.security.handler.MyAuthenticationFailureHandler;
import com.tree.security.handler.MyAuthenticationSuccessHandler;
import com.tree.security.mapper.PermissionMapper;
import com.tree.security.security.MyUserDetailService;
import com.tree.security.utils.MD5Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.*;
import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
//
//import com.mayikt.handler.MyAuthenticationFailureHandler;
//import com.mayikt.handler.MyAuthenticationSuccessHandler;

// Security 配置

/**
 * @author tree
 */
@Component
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private MyAuthenticationFailureHandler failureHandler;
    @Autowired
    private MyAuthenticationSuccessHandler successHandler;

    @Autowired
    private MyUserDetailService userDetailService;
    @Autowired
    private PermissionMapper permissionMapper;

    /**
     * 配置认证用户信息和权限
     *
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        // 添加admin账号
//        auth.inMemoryAuthentication().withUser("admin").password("123456")
//                .authorities("showOrder", "addOrder", "updateOrder", "deleteOrder");
//        // 添加userAdd账号
//        auth.inMemoryAuthentication().withUser("userAdd").password("123456")
//                .authorities("showOrder");
        // 如果想实现动态账号与数据库关联 在该地方改为查询数据库
        auth.userDetailsService(userDetailService).passwordEncoder(new PasswordEncoder() {
            /**
             * 加密密码
             * @param rawPassword
             * @return
             */
            @Override
            public String encode(CharSequence rawPassword) {
                return MD5Util.encode((String)rawPassword);
            }

            /**
             * 验证密码
             * @param rawPassword
             * @param encodedPassword
             * @return
             */
            @Override
            public boolean matches(CharSequence rawPassword, String encodedPassword) {

                return MD5Util.encode((String)rawPassword).equals(encodedPassword);
            }
        });

    }

    /**
     * 系统起来的时候，会直接调用该方法配置拦截请求资源
     *
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
//        // 如何权限控制 给每一个请求路径 分配一个权限名称 让后账号只要关联该名称，就可以有访问权限
//        http.authorizeRequests()
//                // 配置查询订单权限
//                .antMatchers("/showOrder").hasAnyAuthority("showOrder")
//                .antMatchers("/addOrder").hasAnyAuthority("addOrder")
//                //不拦截登录请求
//                .antMatchers("/login").permitAll()
//                .antMatchers("/updateOrder").hasAnyAuthority("updateOrder")
//                .antMatchers("/deleteOrder").hasAnyAuthority("deleteOrder")
//                .antMatchers("/**").fullyAuthenticated().and().formLogin().loginPage("/login")
////		.successHandler(successHandler).failureHandler(failureHandler)
//                .and().csrf().disable();

        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry authorizeRequests= http.authorizeRequests();

        List<Permission> permissions =  permissionMapper.findAllPermission();
        permissions.forEach(permission -> {
            authorizeRequests.antMatchers(permission.getUrl()).hasAnyAuthority(permission.getPermTag());
        });

        authorizeRequests
                .antMatchers("/login").permitAll()
                .antMatchers("/**").fullyAuthenticated()
                .and()
                .formLogin().loginPage("/login")
                .successHandler(successHandler)
//                .failureHandler(failureHandler)
                .and()
                .csrf().disable();

    }

    @Bean
    public static NoOpPasswordEncoder passwordEncoder() {
        return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
    }

//    @Bean
//    public static DelegatingPasswordEncoder passwordEncoder (){
//        String idForEncode = "noop";
//        Map  encoders = new HashMap();
//        encoders.put(idForEncode, new BCryptPasswordEncoder());
//        encoders.put("noop", NoOpPasswordEncoder.getInstance());
//        encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
//        encoders.put("scrypt", new SCryptPasswordEncoder());
//        encoders.put("sha256", new StandardPasswordEncoder());
//        return new DelegatingPasswordEncoder(idForEncode, encoders);
//    }

}
